package com.enjoy.cap10_aop_basic_concepts.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;

import java.util.Arrays;

/**
 * 日志切面类
 * 要记得标注@Aspect注解
 * @param joinPoint joinPoint可以点进去，可以获取很多数据，如方法参数，方法签名等
 * 见 ExposeInvocationInterceptor类中的invoke()方法，AOP中的每个方法都有一个拦截类来处理
 */
@Aspect
public class LogAspects {

    /**
     * 切入点，就是需要拦截的类，方法
     */
    @Pointcut("execution(public int com.enjoy.cap10_aop_basic_concepts.aop.Calculator.*(..))")
    public void pointCut() {
    }

    /**
     * @param joinPoint joinPoint可以点进去，可以获取很多数据，如方法参数，方法签名等
     * @before代表在目标方法执行前切入, 并指定在哪个方法前切入
     * 这里面也可以直接把需要切入的方法传入，如下：
     * @Before("execution(public int com.enjoy.cap10.aop.Calculator.*(..))")
     * 或者指定切入点
     */
    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint) {
        System.out.println("【@Before】" + joinPoint.getSignature().getName() + "除法运行....参数列表是:{" + Arrays.asList(joinPoint.getArgs()) + "}");
    }

    @After("pointCut()")
    public void logEnd(JoinPoint joinPoint) {
        System.out.println("【@After】" + joinPoint.getSignature().getName() + "除法结束......");

    }

	/**
	 *
	 * @param result 返回值
	 */
	@AfterReturning(value = "pointCut()", returning = "result")
    public void logReturn(Object result) {
        System.out.println("【@AfterReturning】" + "除法正常返回......运行结果是:{" + result + "}");
    }

	/**
	 *
	 * @param exception 异常
	 */
	@AfterThrowing(value = "pointCut()", throwing = "exception")
    public void logException(Exception exception) {
        System.out.println("【@AfterThrowing】" + "运行异常......异常信息是:{" + exception + "}");
    }

    /**
     * 通过反射区调用Calculator的div方法，注意Object obj = proceedingJoinPoint.proceed()前后的方方法是在before,after之前输出的
	 * 注意环绕通知的【执行时机】
     */
   /* @Around("pointCut()")
    public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("【@Around】:执行目标方法之前...");
        //相当于开始调div地,断点打到这里，执行test类然后step over,发现进入的是Calculator的div()方法
        Object obj = proceedingJoinPoint.proceed();
        System.out.println("【@Around】:执行目标方法之后...");
        return obj;
    }*/
}
